package com.company.indicationshots.activity;

import android.annotation.SuppressLint;
import android.app.Service;
import android.content.ComponentName;
import android.content.ContentValues;
import android.content.Intent;
import android.content.ServiceConnection;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.graphics.Color;
import android.graphics.Typeface;
import android.os.Bundle;
import android.os.IBinder;
import android.util.Log;
import android.view.Gravity;
import android.view.View;
import android.view.ViewTreeObserver;
import android.widget.HorizontalScrollView;
import android.widget.ImageView;
import android.widget.TableLayout;
import android.widget.TableRow;
import android.widget.TextView;

import androidx.activity.EdgeToEdge;
import androidx.appcompat.app.AppCompatActivity;

import com.company.indicationshots.R;
import com.company.indicationshots.database.DatabaseHelper;
import com.company.indicationshots.model.AnalyseScore;
import com.company.indicationshots.model.Score;
import com.company.indicationshots.services.CommServices;
import com.company.indicationshots.util.CenterOfPoints;
import com.company.indicationshots.util.FindZeroIndices;
import com.company.indicationshots.util.HexToBinaryConverter;
import com.company.indicationshots.view.AnalyseTargetResultView;
import com.company.indicationshots.view.ShotAnalyseBorderView;
import com.company.indicationshots.view.PreShotTargetResultView;
import com.target.communication.service.CommSer;
import com.target.communication.service.ICommData;
import com.target.communication.util.StringUtil;

import java.io.IOException;
import java.util.ArrayList;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.regex.Pattern;
import java.util.stream.Collectors;
import java.util.stream.IntStream;

import cn.hutool.core.collection.CollUtil;
import cn.hutool.core.date.DateUnit;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.StrUtil;
//射靶分析页面
public class ShotAnalyseActivity extends AppCompatActivity {

    private final String TAG = "ShotAnalyseActivity";
    public CommSer commBinder;
    private String serialPortPath = null;
    private Integer baudRate = null;
    private static final Pattern HEX_PATTERN = Pattern.compile("^[0-9A-Fa-f]+$");
    boolean open;
    List<Map<String, Object>> shotList = new ArrayList<>();
    List<Map<String, Object>> aimList = new ArrayList<>();
    TableLayout shotTable;
    HorizontalScrollView tableScroll;
    ImageView aimTarget;
    int bulletCount;
    String shooter = "未指定";
    DatabaseHelper dbHelper;
    SQLiteDatabase db;

    private ServiceConnection conn = new ServiceConnection() {
        @Override
        public void onBindingDied(ComponentName name) {
            ServiceConnection.super.onBindingDied(name);
        }

        //Activity与Service断开连接时回调该方法
        @Override
        public void onServiceDisconnected(ComponentName name) {
            Log.i(TAG, "main onServiceDisconnected");
        }

        //Activity与Service连接成功时回调该方法
        @Override
        public void onServiceConnected(ComponentName name, IBinder service) {
            Log.i(TAG, "main onServiceConnected");
            commBinder = (CommSer) service;
            try {
                commBinder.setSerialPortPath(serialPortPath);
                commBinder.setBaudRate(baudRate);
                openSerial();
            } catch (IOException e) {
                throw new RuntimeException(e);
            }
            commBinder.setiDataSerial(new ICommData() {

                @Override
                public void dataCallBack(byte[] var1) {
                    //接收数据
                    String receiveData = StringUtil.bytesToHex(var1);
                    analyseShot(receiveData);
                }
            });
        }
    };

    @SuppressLint("Range")
    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        EdgeToEdge.enable(this);
        setContentView(R.layout.activity_shot_analyse);


        ShotAnalyseBorderView chestTarget = findViewById(R.id.chest_target);
        ShotAnalyseBorderView loopWireTarget = findViewById(R.id.loop_wire_target);
        ShotAnalyseBorderView exitTrain = findViewById(R.id.exitTrain);
        aimTarget = findViewById(R.id.aimTarget);

        chestTarget.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                chestTarget.setTextColor(Color.parseColor("#FF0000"));
                loopWireTarget.setTextColor(Color.parseColor("#7F0e932e"));
            }
        });

        loopWireTarget.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                loopWireTarget.setTextColor(Color.parseColor("#0e932e"));
                chestTarget.setTextColor(Color.parseColor("#7FFF0000"));
            }
        });

        exitTrain.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                unbindService();
                Intent intent = new Intent(ShotAnalyseActivity.this, MainActivity.class);
                startActivity(intent);
                finish();
            }
        });

        Intent intent = getIntent();
        bulletCount = intent.getIntExtra("bulletCount",30);

        dbHelper = new DatabaseHelper(this);
        db = dbHelper.getWritableDatabase();
        String sql = "select serialPortPath,baudRate from commset";
        Cursor cursor = db.rawQuery(sql, null);
        if (cursor.moveToFirst()) {
            serialPortPath = cursor.getString(cursor.getColumnIndex("serialPortPath"));
            baudRate = cursor.getInt(cursor.getColumnIndex("baudRate"));
        }

        sql = "select name from user where isSelect = 1";
        cursor = db.rawQuery(sql, null);
        if (cursor.moveToFirst()) {
            shooter = cursor.getString(cursor.getColumnIndex("name"));
        }

        cursor.close();

        //绑定串口服务
        if (StrUtil.isNotBlank(serialPortPath) && baudRate != null) {
            bindService();
        }

        tableScroll = findViewById(R.id.tableScroll);
        TableLayout titleTable = findViewById(R.id.titleTable);
        shotTable = findViewById(R.id.shotTable);

        //加载表格左侧标题
        TableRow titleRow1 = new TableRow(this);
        TextView titleTextView1 = new TextView(this);
        titleTextView1.setText("序号");
        titleTextView1.setHeight(30);
        titleTextView1.setTextSize(20);
        titleTextView1.setBackgroundResource(R.drawable.table_first_border);
        titleTextView1.setTextColor(Color.parseColor("#5959B1"));
        titleTextView1.setWidth(64);
        titleTextView1.setGravity(Gravity.CENTER);
        titleRow1.addView(titleTextView1);
        titleTable.addView(titleRow1);

        TableRow titleRow2 = new TableRow(this);
        TextView titleTextView2 = new TextView(this);
        titleTextView2.setText("环数");
        titleTextView2.setHeight(30);
        titleTextView2.setTextSize(20);
        titleTextView2.setBackgroundResource(R.drawable.table_other_border);
        titleTextView2.setTextColor(Color.parseColor("#5959B1"));
        titleTextView2.setWidth(64);
        titleTextView2.setGravity(Gravity.CENTER);
        titleRow2.addView(titleTextView2);
        titleTable.addView(titleRow2);

        TableRow titleRow3 = new TableRow(this);
        TextView titleTextView3 = new TextView(this);
        titleTextView3.setText("时间");
        titleTextView3.setHeight(30);
        titleTextView3.setTextSize(20);
        titleTextView3.setBackgroundResource(R.drawable.table_other_border);
        titleTextView3.setTextColor(Color.parseColor("#5959B1"));
        titleTextView3.setWidth(64);
        titleTextView3.setGravity(Gravity.CENTER);
        titleRow3.addView(titleTextView3);
        titleTable.addView(titleRow3);

        TableRow titleRow4 = new TableRow(this);
        TextView titleTextView4 = new TextView(this);
        titleTextView4.setText("选择->");
        titleTextView4.setHeight(50);
        titleTextView4.setTextSize(15);
        titleTextView4.setTypeface(Typeface.DEFAULT_BOLD);
        titleTextView4.setTextColor(Color.parseColor("#5959B1"));
        titleTextView4.setWidth(64);
        titleTextView4.setGravity(Gravity.CENTER);
        titleRow4.addView(titleTextView4);
        titleTable.addView(titleRow4);

        TableRow row;
        TextView textView;
        ShotAnalyseBorderView borderView;

        for (int i = 0; i < 4; i++) {
            //加载表格内容
            row = new TableRow(this);

            for (int j = 0; j < 10; j++) {
                textView = new TextView(this);
                if (i == 0) {
                    textView.setHeight(30);
                    textView.setTextSize(20);
                    textView.setBackgroundResource(R.drawable.table_first_border);
                    textView.setWidth(57);
                    textView.setGravity(Gravity.CENTER);
                    row.addView(textView);
                } else if (i == 1) {
                    textView.setHeight(30);
                    textView.setTextSize(20);
                    textView.setBackgroundResource(R.drawable.table_other_border);
                    textView.setWidth(57);
                    textView.setGravity(Gravity.CENTER);
                    row.addView(textView);
                } else if (i == 2) {
                    textView.setHeight(30);
                    textView.setTextSize(20);
                    textView.setBackgroundResource(R.drawable.table_other_border);
                    textView.setWidth(57);
                    textView.setGravity(Gravity.CENTER);
                    row.addView(textView);
                } else {
                    borderView = new ShotAnalyseBorderView(this, "不绘制");
                    borderView.setHeight(50);
                    borderView.setWidth(57);
                    row.addView(borderView);
                }
            }

            shotTable.addView(row);
        }

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                TableRow tableRow = (TableRow) shotTable.getChildAt(3);
                ShotAnalyseBorderView select;
                // 遍历TableRow中的所有View
                for (int j = 0; j < tableRow.getChildCount(); j++) {
                    select = (ShotAnalyseBorderView) tableRow.getChildAt(j);
                    select.setOnClickListener(new View.OnClickListener() {
                        ShotAnalyseBorderView bv1;
                        ShotAnalyseBorderView bv2;

                        @Override
                        public void onClick(View v) {
                            bv1 = (ShotAnalyseBorderView) v;
                            String tag = (String) v.getTag();
                            if ("clicked".equals(tag)) {
                                bv1.setColor("#888888", "#FFFFFF");
                                v.setTag("notClick");
                            } else {
                                for (int i = 0; i < tableRow.getChildCount(); i++) {
                                    bv2 = (ShotAnalyseBorderView) tableRow.getChildAt(i);
                                    bv2.setColor("#888888", "#FFFFFF");
                                }
                                bv1.setColor("#FF0000", "#FF0000");
                                v.setTag("clicked");
                            }
                        }
                    });
                }
            }
        });

    }

    int shotNum;
    float time;
    List<AnalyseScore> scoreList = new ArrayList<>();
    int length;
    String prevReData;
    AnalyseTargetResultView targetResultView = new AnalyseTargetResultView();
    AnalyseScore analyseScore;
    List<Date> timeList = new ArrayList<>();
    Map<Integer,List<Map<String,Object>>> saveAimList = new HashMap<>();

    //训练分析射靶
    private void analyseShot(String receiveData) {

        //瞄准点数据
        if (receiveData.startsWith("1100") && receiveData.endsWith("0000") && receiveData.length() == 20 && (HEX_PATTERN.matcher(receiveData.substring(4, 16)).matches())) {

            if (shotNum >= bulletCount){
                return;
            }

            timeList.add(new Date());

            prevReData = receiveData;

            Map<String, Object> xyMap = calCoord(receiveData);

            //胸环靶
            aimList.add(xyMap);

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    targetResultView.getTargetView(ShotAnalyseActivity.this, shotList, aimList, aimTarget);
                }
            });

        }

        //射靶
        if ("0100".equals(receiveData)) {

            //成绩序号
            shotNum++;

            //当成绩序号大于子弹数量，直接返回，不能继续射靶了
            if (shotNum > bulletCount){
                return;
            }
            //胸环靶的宽和高
            int width = 1901;
            int height = 1901;
            float dis;
            float num;
            //计算最高环数坐标
            float highestX = (float) width / 2 - 20;
            float highestY = (float) height / 2 + 168;
            //计算环数半径
            float radius = (float) width / (10 * 10);
            float ring;
            String formatRing;

            //枪数据不为空
            if(StrUtil.isNotBlank(prevReData)){
                //计算枪靶数据的时间差
                Date aimTime = timeList.get(timeList.size() - 1);
                long ms = DateUtil.between(aimTime, new Date(), DateUnit.MS, false);

                if (ms <= 300){
                    Map<String, Object> xyMap = calCoord(prevReData);
                    float x = (float) xyMap.get("x");
                    float y = (float) xyMap.get("y");
                    shotList.add(xyMap);

                    //计算环数,计算触发点的坐标和最高环，也就是靶10环中心，之间的距离
                    dis = (float) Math.sqrt((x - highestX) * (x - highestX) + (y - highestY) * (y - highestY));
                    //计算触发点坐标和最高环的环数差
                    num = dis / radius;
                    //计算当前触发点的环数，保留两位小数
                    ring = (float) (Math.round((10.9 - num * 0.1) * 10.0) / 10.0);
                    formatRing = String.valueOf(ring);
                } else {
                    formatRing = "----";
                }
            } else {
                formatRing = "----";
            }

            //胸环靶
            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    targetResultView.getTargetView(ShotAnalyseActivity.this, shotList, new ArrayList<>(), aimTarget);
                }
            });

            //表格
            //计算每次成绩耗时
            if (timeList.size() > 1) {
                long ms = DateUtil.between(timeList.get(0), new Date(), DateUnit.MS, false);
                double second = (double) ms / 1000.0;
                time = (float) (Math.round(second * 10.0) / 10.0);
            } else {
                time = 0;
            }

            analyseScore = new AnalyseScore(String.valueOf(shotNum), formatRing, String.valueOf(time));
            scoreList.add(analyseScore);

            //当成绩不足10发时，补空数据达到十环，为了进行表格的绘制
            length = scoreList.size();
            if (length < 10) {
                int diff = 10 - length;
                List<AnalyseScore> addAimShotDataList = IntStream.range(0, diff)
                        .mapToObj(i -> new AnalyseScore("", "", ""))
                        .collect(Collectors.toList());
                scoreList.addAll(addAimShotDataList);
            }

            runOnUiThread(new Runnable() {
                @Override
                public void run() {
                    // 清除shotTable中的所有视图
                    shotTable.removeAllViews();
                }
            });

            TextView textView;
            ShotAnalyseBorderView borderView;
            TableRow row;
            String order;

            //绘制表格
            for (int i = 0; i < 4; i++) {
                row = new TableRow(this);

                for (int j = 0; j < scoreList.size(); j++) {
                    textView = new TextView(this);
                    if (i == 0) {
                        textView.setText(scoreList.get(j).getNum());
                        textView.setTextColor(Color.WHITE);
                        textView.setHeight(30);
                        textView.setTextSize(20);
                        textView.setBackgroundResource(R.drawable.table_first_border);
                        textView.setWidth(57);
                        textView.setGravity(Gravity.CENTER);
                        row.addView(textView);
                    } else if (i == 1) {
                        textView.setText(scoreList.get(j).getRing());
                        textView.setTextColor(Color.RED);
                        textView.setHeight(30);
                        textView.setTextSize(20);
                        textView.setBackgroundResource(R.drawable.table_other_border);
                        textView.setWidth(57);
                        textView.setGravity(Gravity.CENTER);
                        row.addView(textView);
                    } else if (i == 2) {
                        textView.setText(scoreList.get(j).getTime());
                        textView.setTextColor(Color.RED);
                        textView.setHeight(30);
                        textView.setTextSize(20);
                        textView.setBackgroundResource(R.drawable.table_other_border);
                        textView.setWidth(57);
                        textView.setGravity(Gravity.CENTER);
                        row.addView(textView);
                    } else {
                        order = scoreList.get(j).getNum();
                        if (StrUtil.isNotBlank(order)) {
                            borderView = new ShotAnalyseBorderView(this, "绘制");
                        } else {
                            borderView = new ShotAnalyseBorderView(this, "不绘制");
                        }
                        borderView.setText(order);
                        borderView.setTextColor(Color.parseColor("#FF0e932e"));
                        borderView.setGravity(Gravity.CENTER);
                        borderView.setTextSize(20);
                        borderView.setHeight(50);
                        row.addView(borderView);
                    }
                }

                TableRow finalRow = row;
                runOnUiThread(new Runnable() {
                    @Override
                    public void run() {
                        shotTable.addView(finalRow);
                    }
                });

            }

            //表格自动滑动到最新成绩一行
            ViewTreeObserver vto = tableScroll.getViewTreeObserver();
            vto.addOnGlobalLayoutListener(new ViewTreeObserver.OnGlobalLayoutListener() {
                @Override
                public void onGlobalLayout() {
                    tableScroll.getViewTreeObserver().removeOnGlobalLayoutListener(this);
                    if (length > 10) {
                        //滑动
                        tableScroll.smoothScrollTo(64 + length * 57, 0);
                    }
                }
            });

            //当射靶成绩不足10时，清除集合多余空数据
            if (length < 10) {
                scoreList.subList(length, scoreList.size()).clear();
            }

            saveAimList.put(shotNum,aimList);
            aimList = new ArrayList<>();
            prevReData = null;
            timeList = new ArrayList<>();

        }

        //拉栓，保存数据
        if ("0101".equals(receiveData)){

            reset();

            if(CollUtil.isNotEmpty(scoreList)){
                String date = DateUtil.format(DateUtil.date(),"yyyy-MM-dd HH:mm:ss");
                ContentValues values = new ContentValues();
                values.put("shooter",shooter);
                values.put("createTime",date);
                long trainRecordId = db.insert("trainRecord", null, values);

                long trainScoreId;
                List<Map<String, Object>> maps;
                for (AnalyseScore score : scoreList) {
                    values = new ContentValues();
                    values.put("num",score.getNum());
                    values.put("ring",score.getRing());
                    values.put("time",score.getTime());
                    values.put("trainRecordId",trainRecordId);
                    values.put("createTime",date);
                    trainScoreId = db.insert("trainScore", null, values);
                    maps = saveAimList.get(Integer.parseInt(score.getNum()));
                    values = new ContentValues();
                    for (Map<String, Object> map : maps) {
                        values.put("x", (float) map.get("x"));
                        values.put("y",(float) map.get("y"));
                        values.put("trainScoreId",trainScoreId);
                        values.put("createTime",date);
                        db.insert("aimPoint",null,values);
                    }
                }
            }

        }

    }

    //瞄准点绘制轨迹
    private Map<String, Object> calCoord(String receiveData) {
        String info;
        String wOps;
        String hOps;
        float x;
        float y;
        //胸环靶的宽和高
        int width = 1901;
        int height = 1901;
        // 计算每个格子的宽度和高度
        float gridWidth = (float) width / 24;
        float gridHeight = (float) height / 24;
        //获取靶数据有效部分
        info = receiveData.substring(4, 16);
        //转成二进制字符串
        info = HexToBinaryConverter.hexToBinary(info);

        //计算位置坐标
        //截取字符串前24位为纵向靶数据
        hOps = info.substring(0, 24);
        //截取字符串后24位为横向靶数据
        wOps = info.substring(24);
        //纵向靶数据找出其中所有字符0所在位置返回一个集合，0代表被触发的格子位置，获得纵向触发格子位置集合
        List<Integer> hIndices = FindZeroIndices.zeroIndices(hOps);
        //横向靶数据找出其中所有字符0所在位置返回一个集合，0代表被触发的格子位置，获得横向触发格子位置集合
        List<Integer> wIndices = FindZeroIndices.zeroIndices(wOps);
        float iy;
        float ix;
        Score score;
        List<Score> scList = new ArrayList<>();
        //当两个集合中有一个元素个数大于1时，遍历纵向和横向位置集合
        if (hIndices.size() > 1 || wIndices.size() > 1) {
            for (Integer hIndex : hIndices) {
                for (Integer wIndex : wIndices) {
                    //计算当前触发格子的纵坐标和横坐标
                    iy = hIndex * gridHeight;
                    ix = wIndex * gridWidth;
                    score = new Score(0, 0, null, null, ix, iy, 0);
                    scList.add(score);
                }
            }
            //计算所有被触发坐标点的中心坐标
            Score centerPoint = CenterOfPoints.calculateCenter(scList);
            x = centerPoint.getX();
            y = centerPoint.getY();
        } else {
            //当两个集合都只有一个元素时，直接计算触发点的坐标
            x = wIndices.get(0) * gridWidth;
            y = hIndices.get(0) * gridHeight;
        }

        Map<String, Object> map = new HashMap<>();
        map.put("x", x);
        map.put("y", y);

        return map;
    }

    //重置页面
    private void reset(){

        runOnUiThread(new Runnable() {
            @Override
            public void run() {
                recreate();
            }
        });

    }

    //串口服务
    /*
     *   绑定服务
     * */
    public void bindService() {
        Intent intent = new Intent(this, CommServices.class);
        intent.putExtra("param", "param1");
        Log.i(TAG, "main bindService");
        bindService(intent, conn, Service.BIND_AUTO_CREATE);
    }

    //解绑服务
    private void unbindService() {
        if (commBinder == null) {
            Log.i(TAG, "main unbindService,binder is null");
            return;
        }
        unbindService(conn);
        commBinder = null;
        Log.i("main unbindService", "main unbindService success");
    }

    //打开串口
    public void openSerial() throws IOException {
        open = commBinder.connSerial();
        Log.i("main openSerial", "main serial open success");
    }

    @Override
    protected void onDestroy() {
        super.onDestroy();

    }
}